#pragma once

#include "ColligereDatabaseLayoutBase.hpp"
#include "ColligereListCtrl.hpp"
#include "ColligereAudioDbTreeCtrl.hpp"
#include "ColligereDataImporterBase.hpp"
#include "ColligereDataExporterBase.hpp"
#include "ColligereSearchFreeDbPanel.hpp"
#include "ColligereSearchDiscogsPanel.hpp"
#include "ColligereDatabaseInterfaceBase.hpp"

namespace col 
{

enum
{
	ID_PropertyGrid_ReleaseInfo = 12000
};

wxDEFINE_EVENT ( COLLIGERE_CMD_DATAGETTER_THREAD_COMPLETED, wxCommandEvent );

struct BrowseByClientData : public wxClientData
{
public:
	BrowseByClientData ( wxUint32 browseBy ) : mBrowseBy ( browseBy ) { }
	wxUint32 GetBrowseBy() const { return mBrowseBy; }
private:
	wxUint32 mBrowseBy;
};

//! A layout for showing information from an audio collection database.
class AudioDatabaseLayout : public DatabaseLayoutBase, private wxThreadHelper
{
public:
	AudioDatabaseLayout ( wxWindow *pParentWnd, DatabaseInterfaceBase *pParentInterface );
	virtual ~AudioDatabaseLayout();

	wxUint32 GetDatabaseId() const;
	
	void Create();
	void Close();

	void ProcessParentEvent ( wxEvent &rEvent );

	void PassItemToInputControls ( const DatabaseItemBase &rItem );
	const Artist &GetItemFromInputControls();

	bool IsDatabaseItemListShown() const;
	bool IsRecycleBinShown() const;
	bool IsSearchDiscogsShown() const;
	bool IsSearchFreeDbShown() const;

	void ShowDatabaseItems ( bool show = true );
	void ShowRecycleBin ( bool show = true );
	void ShowSearchDiscogs ( bool show = true );
	void ShowSearchFreeDb ( bool show = true );

	const wxString GetStatusText ( wxUint32 statBarColumn ) const;
	const wxString GetTitleText() const;

	void LoadLayout();
	void SaveLayout();

	void SelectItem ( const DatabaseItemBase &rItem, bool select = true );
	
	void UnselectActiveItem();

	const TreeItemData *GetSelectedItemData() const;

	const DatabaseItemBase &GetPrevParsedItem() const { return mPrevParsed; }
protected:
	virtual wxThread::ExitCode Entry();
private:
	wxUint32 GetAlbumItemCount ( const wxTreeItemId &rRoot = 0 ) const;
	wxUint32 GetArtistItemCount ( const wxTreeItemId &rRoot = 0 ) const;

	bool IsArtistItem ( const wxTreeItemId &rItem ) const;
	bool IsAlbumItem ( const wxTreeItemId &rItem ) const;

	class AlbumNodeCounter : public std::unary_function < wxTreeItemId, void >
	{
	public:
		AlbumNodeCounter ( const wxTreeCtrl *pCtrl, wxUint32 &rResult );
		void operator() ( wxTreeItemId item );
	private:
		const wxTreeCtrl *mpCtrl;
		wxUint32 &mrResult;
	};

	class ArtistNodeCounter : public std::unary_function < wxTreeItemId, void >
	{
	public:
		ArtistNodeCounter ( const wxTreeCtrl *pCtrl, wxUint32 &rResult );
		void operator() ( wxTreeItemId item );
	private:
		const wxTreeCtrl *mpCtrl;
		wxUint32 &mrResult;
	};

	//! Connects all event handlers.
	void ConnectEventHandlers();

	void CreateLayout();
	void CreateNotebookLayout();
	void CreateRecycleBin();
	void CreateDatabaseItemList();
	void CreateSearchFreeDbPanel();
	void CreateSearchDiscogsPanel();

	void CreateReleaseInfoPage();
	void CreateTracksPage();
	void CreateNotesPage();

	/////////////////////////////////////////////////
	// Event handlers
	/////////////////////////////////////////////////

	void OnPropertyGridChanged( wxPropertyGridEvent &rE );

	void OnPaneButton ( wxAuiManagerEvent &rEvent );
	
	void OnItemChanged ( wxTreeEvent &rEvent );
	void OnItemRightClicked ( wxTreeEvent &rEvent );
	
	void OnTrackTitleText ( wxCommandEvent &rEvent );
	
	void OnBrowseBySelected ( wxCommandEvent &rEvent );
	
	void OnButtonAddTrack ( wxCommandEvent &rEvent );
	void OnButtonDeleteTrack ( wxCommandEvent &rEvent );
	void OnButtonEditTrack ( wxCommandEvent &rEvent );
	
	void OnRecycleBinItemRightClick ( wxListEvent &rEvent );
	
	void OnPopupMenuRestoreRecBinItem ( wxCommandEvent &rEvent );
	void OnPopupMenuRemRecBinItemPerm ( wxCommandEvent &rEvent );
	
	void OnRecBinKeyDown ( wxListEvent &rEvent );
	
	void OnTrackSelected ( wxListEvent &rEvent );
	void OnTrackDeselected ( wxListEvent &rEvent );
	void OnTrackActivated ( wxListEvent &rEvent );

	void OnDatabaseDeleteEvent ( AudioDatabaseEvent &rEvt );
	void OnDatabaseRestoreEvent ( AudioDatabaseEvent &rEvt );
	void OnDatabaseChangeEvent ( AudioDatabaseEvent &rEvt );
	void OnDatabaseAddEvent ( AudioDatabaseEvent &rEvt );
	void OnDatabasePostEvent ( AudioDatabaseEvent &rEvt );
	void OnDatabaseCloseEvent ( AudioDatabaseEvent &rEvt );
	void OnDatabaseQueryEvent ( AudioDatabaseEvent &rEvt );
	void OnDatabaseCommitEvent ( AudioDatabaseEvent &rEvt );
	void OnDatabaseEvent ( AudioDatabaseEvent &rEvt );

	void OnImport ( DataImporterEvent &rEvt );
	void OnExport ( DataExporterEvent &rEvt );

	void OnThreadCompleted ( wxCommandEvent &rEvt );
	void OnClose ( wxCloseEvent &rEvt );

	DatabaseInterfaceBase *mpParentInterface;

	typedef std::map < long, const Album * > RecycleBinItemDataMap;
	//! List of item data objects for the recycle bin.
	RecycleBinItemDataMap mRecycleBinCtrlItemData;
	wxUint32 mNextRecBinItemDataPosCounter;

	//////////////////////////////////////
	// Layout controls
	//////////////////////////////////////

	wxPropertyGrid *mpReleaseInfoCtrl;

	//! The audio database layout manager.
	wxAuiManager mLayoutMngr;

	DatabaseTreeCtrlBase *mpDatabaseItemsCtrl;
	
	ColligereListCtrl *mpRecycleBinCtrl, *mpTracksCtrl;
	wxTextCtrl *mpNotesCtrl, *mpTagsCtrl;
	
	wxComboBox *mpBrowseByCtrl;

	//! The panel which contains the database item list and the "Browse by" box.
	wxPanel *mpItemsPanel;
	ColligereSearchFreeDbPanel *mpSearchFreeDbPanel;
	ColligereSearchDiscogsPanel *mpSearchDiscogsPanel;
	wxAuiNotebook *mpNotebookLayout;
	
	wxTextCtrl *mpTrackLenCtrl, *mpTrackTitleCtrl, *mpTrackNumCtrl;
	
	wxButton *mpDeleteTrackButton, *mpEditTrackButton;
	wxBitmapButton *mpAddTrackButton;

	wxProgressDialog *mpSaveProgDlg, *mpOpenProgDlg, *mpImportProgDlg, *mpExportProgDlg;

	wxPGChoices mFormatChoices, mGenreChoices, mCountryChoices, 
		mConditionChoices, mStatusChoices, mRatingChoices;

	//////////////////////////////////////
	// Misc.
	//////////////////////////////////////

	Artist mPrevParsed, mCurParsed;
};

}